using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Text.RegularExpressions;

namespace DiceRoller.GUI{

  public partial class frmMain : Form{

		private System.Collections.ArrayList history;
		private int index;

    public frmMain(){
      InitializeComponent();
			history = new System.Collections.ArrayList();
			index = 0;
      txtTarget.Text = "7";
    }

    private void btnRoll_Click(object sender, EventArgs e){
      rollDice();
    }

    private void rollDice(){
      string sNumDice;
      int numDice;
      int[] rolledDice;

      sNumDice = txtNumberDice.Text;
			if(Regex.Match(sNumDice, "[0-9]+").Success && Regex.Match(txtTarget.Text,"[0-9]+").Success) {

				numDice = Convert.ToInt32(sNumDice);

				rolledDice = roll(numDice);

				txtDiceDisplay.Text = String.Empty;

				for(int i = 0; i < numDice; i++) {
					txtDiceDisplay.Text += (rolledDice[i]).ToString() + " ";
				}

				txtDiceDisplay.Text = txtDiceDisplay.Text.Trim();

				txtSuccesses.Text = (exaltedSuccesses(rolledDice)).ToString();
				setBotchedStatus();
				txtHistory.Text = txtSuccesses.Text + (txtSuccesses.Text.Equals("BOTCHED") ? "   " : " Successes") + " - " + txtDiceDisplay.Text + System.Environment.NewLine + txtHistory.Text;
				history.Add(sNumDice);
				index = history.Count-1;
			}
    }

		private void setBotchedStatus(){
			if(txtSuccesses.Text.Trim().Equals("0") && countElements(txtDiceDisplay.Text.Split(),"1") >= 1 && !cboDamage.Checked){
				txtSuccesses.Text = "BOTCHED";
			}
		}

    private int exaltedSuccesses(int[] rolledDice) {
      int successes = 0;

      for(int i = 0; i < rolledDice.Length; i++) {
        if(rolledDice[i] == 0) {
          successes += cboDamage.Checked? 1 : 2;
        }
        else if(rolledDice[i] >= Convert.ToInt32(txtTarget.Text)) {
          successes += 1;
        }
      }
      return successes;
    }

    private int[] roll(int numDice) {
      int[] rolledDice = new int[numDice];
      System.Random r = new System.Random(Convert.ToInt32((DateTime.Now).Ticks % Int32.MaxValue));

      for(int i = 0; i < numDice; i++) {
        rolledDice[i] = r.Next(0, 9);
      }
      return rolledDice;
    }

    private void txtNumberDice_KeyDown(object sender, KeyEventArgs e) {
      switch(e.KeyCode) {
        case Keys.Enter: 
          rollDice();
          break;
        case Keys.Escape: 
          txtNumberDice.Text = "";
					txtNumberDice.Focus();
          break;
				case Keys.Up:
					if(index >= 1 && sender.Equals(txtNumberDice)) {
						txtNumberDice.Text = Convert.ToString(history.ToArray()[--index]);
					}
					break;
				case Keys.Down:
					if(index < history.Count - 1 && sender.Equals(txtNumberDice)) {
						txtNumberDice.Text = Convert.ToString(history.ToArray()[++index]);
					}
					break;
      }
    }

    private void cboDamage_CheckedChanged(object sender, EventArgs e) {
      string[] dice;
			int successes;
      int zeroes;

			if(!txtSuccesses.Text.Equals(System.String.Empty)) {
				if(!txtSuccesses.Text.Equals("BOTCHED")) {
					successes = Convert.ToInt32(txtSuccesses.Text);
				}
				else {
					successes = 0;
				}


				dice = txtDiceDisplay.Text.Split(" ".ToCharArray());

				zeroes = countElements(dice, "0");

				txtSuccesses.Text = (cboDamage.Checked ? successes - zeroes : successes + zeroes).ToString();
				setBotchedStatus();
				txtHistory.Text = txtSuccesses.Text + (txtSuccesses.Text.Equals("BOTCHED") ? "   " : " Successes") + " - " + txtDiceDisplay.Text + System.Environment.NewLine + txtHistory.Text;
			}
    }

		private int countElements(object[] list, object element) {
			int count = 0;
			for(int i = 0; i < list.Length; i++) {
				count += list[i].Equals(element) ? 1 : 0;
			}
			return count;
		}

	}
}
